/**
 * Classname :AccountManagerImpl.java
 *
 * Version information: 1.0
 *
 * Date: Dec 06, 2011 ho.viet.duan create
 *
 * MDG Viet Nam co.ltd, All Rights Reserved.
 */
package com.zho.business.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import com.zho.business.AccountManager;
import com.zho.common.Constants.TemplateFile;
import com.zho.common.domain.db.PagingInfo;
import com.zho.common.domain.db.SearchResult;
import com.zho.common.utility.Constants.Active;
import com.zho.common.utility.Constants.UniqueCode;
import com.zho.domain.bean.CgsCustomer;
import com.zho.domain.model.CustomerCondition;
import com.zho.domain.model.CustomerInfo;
import com.zho.util.Constants.Address;
import com.zho.util.Helpers;
import com.zho.util.Logit;
import com.zho.util.RandomHelper;
import com.zho.util.StringHelpers;

/**
 * 
 * @author Ho.Viet.Duan Created Dec 06, 2011
 */
public class AccountManagerImpl extends BaseManager implements
		AccountManager {
	private Logit log = Logit.getInstance(AccountManagerImpl.class);

	/**
	 * get Customer by Name (for spring security)
	 * 
	 * @param
	 * @return Customer Info
	 * @auth ho.viet.duan
	 * @CrDate Dec 14, 2011
	 */
	public CustomerInfo getCustomerByEmail(String email) throws Exception {
		CustomerInfo customerInfo = null;
		CgsCustomer cgsCustomer = null;

		try {
			cgsCustomer = getCgsCustomerDAO().findByEmailAddress(email);
			if (cgsCustomer != null) {
				customerInfo = new CustomerInfo();
				BeanUtils.copyProperties(cgsCustomer, customerInfo);
				
				// Get Statistic
				//Integer betsCreatedCount 	= getCgsBetDAO().countByCustomer(cgsCustomer.getCustomerId());
				//Integer betsJoinedCount		= getCgsCustBetPosDAO().countJoinedByCustomer(cgsCustomer.getCustomerId());
				//Long friendCount  			= getCgsFriendListDAO().countFriends(cgsCustomer.getCustomerId());
				//AccountStatusInfo accountStatusInfo = new AccountStatusInfo();
				//accountStatusInfo.setBetsCreatedCount(betsCreatedCount);
				//accountStatusInfo.setBetsJoinedCount(betsJoinedCount);
				//accountStatusInfo.setFriendCount(friendCount);
				//customerInfo.setAccountStatusInfo(accountStatusInfo);
			}
		} catch (Exception e) {
			// TODO: handle exception
			throw e;
		}

		return customerInfo;
	}

	/**
	 * get Customer by Id (for spring security)
	 * 
	 * @param
	 * @return Customer Info
	 * @auth ho.viet.duan
	 * @CrDate Dec 14, 2011
	 */
	public CustomerInfo getCustomerById(String id) throws Exception {
		CustomerInfo customerInfo = null;
		CgsCustomer cgsCustomer = null;
		try {
			if (!StringUtils.isEmpty(id)) {
				cgsCustomer = getCgsCustomerDAO().findById(id);
				if (cgsCustomer != null) {
					customerInfo = new CustomerInfo();
					BeanUtils.copyProperties(cgsCustomer, customerInfo);					
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			throw e;
		}
		return customerInfo;
	}	
	
	/**
	 * add Customer
	 * 
	 * @auth ho.viet.duan
	 * @CrDate Dec 14, 2011
	 */
	public Integer addCustomer(CustomerInfo customerInfo) throws Exception {

		if (customerInfo != null) {
			CgsCustomer cgsCustomer = new CgsCustomer();
			BeanUtils.copyProperties(customerInfo, cgsCustomer);
			
			// Generate Id
			String customerId = getCgsUidDAO().genSequenceId("", UniqueCode.CUSTOMER);
			cgsCustomer.setCustomerId(customerId);
			
			// Encode MD5 pass
			cgsCustomer.setPassword(encodeString(cgsCustomer.getPassword()));
			// Save into database
			cgsCustomer.setInputDate(new Date());
			cgsCustomer.setUpdateDate(new Date());
			cgsCustomer.setActiveFlg(Active.INACTIVE);
			cgsCustomer.setDiscount(new BigDecimal(0));
			getCgsCustomerDAO().save(cgsCustomer);
			
			// Prepare parameters
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("fullname", !StringUtils.isEmpty(cgsCustomer.getCustomerName())? cgsCustomer.getCustomerName(): cgsCustomer.getEmailAddress());
			params.put("code", StringHelpers.encryptString(cgsCustomer.getCustomerId()));
			params.put("url", Helpers.getCgsProperty(Address.WEB_URL));

			// Send mail confirmation
			final String subject = "Activation Confirm!";
			final String to = cgsCustomer.getEmailAddress();
			sendMail(to, subject, TemplateFile.MAIL_ACTIVE_ACCOUNT, params);
		}
		return 0;
	}

	/**
	 * Update customer's profile
	 */
	public Integer updateCustomer(CustomerInfo customerInfo, Integer type) throws Exception {

		if (customerInfo != null && !StringUtils.isEmpty(customerInfo.getCustomerId())) {

			if (!StringUtils.isEmpty(customerInfo.getNewPassword())) {
				customerInfo.setPassword(encodeString(customerInfo.getNewPassword()));
			}

			CgsCustomer cgsCustomer = new CgsCustomer();
			BeanUtils.copyProperties(customerInfo, cgsCustomer);			
			cgsCustomer.setUpdateDate(new Date());
			getCgsCustomerDAO().updateProfilePicture(cgsCustomer);
			//getCgsCustomerDAO().updatePassword(cgsCustomer);
		}
		return 0;
	}

	/**
	 * Reset password
	 */
	public Integer updatePassword(CustomerInfo customerInfo) throws Exception {
		log.info("Update password:");
		CgsCustomer cgsCust = null;
		if (customerInfo != null) {
			if (!StringUtils.isEmpty(customerInfo.getCustomerId())) {
				cgsCust = getCgsCustomerDAO().findById(customerInfo.getCustomerId());	
			} else if (!StringUtils.isEmpty(customerInfo.getEmailAddress())) {
				cgsCust = getCgsCustomerDAO().findByEmailAddress(customerInfo.getEmailAddress());
			}
			if (cgsCust != null) {
				// Reset password
				String resetPassword = RandomHelper.generatePassword();
				CgsCustomer cgsCustomer = new CgsCustomer();
				cgsCustomer.setCustomerId(customerInfo.getCustomerId());
				cgsCustomer.setPassword(encodeString(resetPassword));
				cgsCustomer.setUpdateDate(new Date());
				getCgsCustomerDAO().updatePassword(cgsCustomer);
				
				// Send mail to inform			
				Map<String, Object> params = new HashMap<String, Object>();
				if (!StringUtils.isEmpty(cgsCust.getCustomerName()))
					params.put("fullname", cgsCust.getCustomerName());
				else params.put("fullname", cgsCust.getEmailAddress());
	
				params.put("password", resetPassword);
	
				// Send mail confirmation
				final String subject = "Reset Password!";
				final String to = cgsCust.getEmailAddress();	
				sendMail(to, subject, TemplateFile.MAIL_RESET_PASSWORD, params);
			}
		}
		return 0;
	}

	/**
	 * Search customer by condition and using paging
	 * @auth ho.viet.duan
	 * @CrDate Dec 19, 2011
	 */
	public SearchResult<CustomerInfo> listCustomer(CustomerInfo customerInfo, PagingInfo pagingInfo, String orderColumn) throws Exception {

		SearchResult<CustomerInfo> listCustomerInfo	= new SearchResult<CustomerInfo>(); 
		SearchResult<CgsCustomer> listCgsCustomer	= null;
   	 	try {
			 // Build condition to search
			 CustomerCondition condition = new CustomerCondition();
			 if (customerInfo != null) {
				 if (customerInfo.getEmailAddress() != null)
					 condition.setEmailAddress(customerInfo.getEmailAddress());
				 if (customerInfo.getCustomerId() != null)
					 condition.setCustomerId(customerInfo.getCustomerId());
				 if (customerInfo.getActiveFlg() != null)
					 condition.setActiveFlg(customerInfo.getActiveFlg());
				 if (customerInfo.getDob() != null)
					 condition.setDob(customerInfo.getDob());
			 }

			 listCgsCustomer = getCgsCustomerDAO().listCgsCustomer(condition, pagingInfo, orderColumn);
				
			if (listCgsCustomer != null && listCgsCustomer.size() > 0) {
				// Init result
				listCustomerInfo = new SearchResult<CustomerInfo>();
				// Set paging into result
				listCustomerInfo.setPagingInfo(listCgsCustomer.getPagingInfo());
				
				for (CgsCustomer cgsCustomer : listCgsCustomer) {
					CustomerInfo custInfo = new CustomerInfo();
					// Copy customer information
					BeanUtils.copyProperties(cgsCustomer, custInfo);

					// Add Customer Info into result
					listCustomerInfo.add(custInfo);
				}
			}
		 } catch (Exception e) {
			 throw e;
		 }
        return listCustomerInfo;
	}

	/**
	 * Invite friend list
	 */
	public void inviteFriendList(List<String> mailList) throws Exception {
		
		// Get template
		String pathFile = Helpers.getFullPath(TemplateFile.MAIL_INVITE_TO_CGS);

		// Send mail confirmation
		final String subject = "Invite to CGS!";
		for (String email : mailList) {
			final String to = email;
			sendMail(to, subject, TemplateFile.MAIL_INVITE_TO_CGS, null);
		}
	}
}